<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>纹样修复师</title>
    <style>
        @keyframes fall-down {
            from {
                transform: translateY(-100vh); /* 从屏幕上方外开始 */
                opacity: 1;
            }
            to {
                transform: translateY(100vh); /* 落到屏幕下方外 */
                opacity: 0.3;
            }
        }

        body {
            font-family: 'Comic Sans MS', '楷体', sans-serif;
            background-color: #f0f9ff;
            margin: 0;
            padding: 20px;
            display: flex;
            flex-direction: column;
            align-items: center;
            overflow-x: hidden;
        }

        h1 {
            color: #ff6b6b;
            text-shadow: 3px 3px 0 #ffe66d, 6px 6px 0 #4ecdc4;
            font-size: 3rem;
            margin-bottom: 20px;
            animation: bounce 2s infinite;
        }

        @keyframes bounce {
            0%, 100% {
                transform: translateY(0);
            }
            50% {
                transform: translateY(-10px);
            }
        }

        .container {
            display: flex;
            gap: 20px;
            width: 100%;
            max-width: 1000px;
        }

        .left-panel, .right-panel {
            display: flex;
            flex-direction: column;
            gap: 15px;
            width: 150px;
        }

        button {
            background-color: #4ecdc4;
            color: white;
            border: none;
            border-radius: 50px;
            padding: 12px 15px;
            font-size: 1.1rem;
            cursor: pointer;
            font-weight: bold;
            box-shadow: 0 4px 0 #2a9d8f;
            transition: all 0.2s;
            text-align: center;
        }

        button:hover {
            transform: translateY(-2px);
            box-shadow: 0 6px 0 #2a9d8f;
        }

        button:active {
            transform: translateY(2px);
            box-shadow: 0 2px 0 #2a9d8f;
        }

        .pattern-btn {
            background-color: #ff9f1c;
            box-shadow: 0 4px 0 #cc7e16;
        }

        .pattern-btn:hover {
            box-shadow: 0 6px 0 #cc7e16;
        }

        .pattern-btn:active {
            box-shadow: 0 2px 0 #cc7e16;
        }

        .clear-btn {
            background-color: #ff6b6b;
            box-shadow: 0 4px 0 #d64545;
        }

        .clear-btn:hover {
            box-shadow: 0 6px 0 #d64545;
        }

        .clear-btn:active {
            box-shadow: 0 2px 0 #d64545;
        }

        .complete-btn {
            background-color: #6bff6b;
            box-shadow: 0 4px 0 #45d645;
        }

        .complete-btn:hover {
            box-shadow: 0 6px 0 #45d645;
        }

        .complete-btn:active {
            box-shadow: 0 2px 0 #45d645;
        }

        .canvas-container {
            position: relative;
            flex-grow: 1;
        }

        canvas {
            background-color: white;
            border: 4px solid #4ecdc4;
            border-radius: 10px;
            box-shadow: 0 8px 16px rgba(0, 0, 0, 0.1);
        }

        .star {
            position: absolute;
            background-color: gold;
            width: 10px;
            height: 10px;
            border-radius: 50%;
            pointer-events: none;
            animation: fall 2s ease-out forwards;
        }

        @keyframes fall {
            0% {
                transform: translateY(0) rotate(0deg) scale(1);
                opacity: 1;
            }
            100% {
                transform: translateY(100vh) rotate(360deg) scale(0);
                opacity: 0;
            }
        }

        .error-point {
            position: absolute;
            width: 10px;
            height: 10px;
            background-color: red;
            border-radius: 50%;
            transform: translate(-5px, -5px);
        }

        /* 新增样式 */
        .generated-line {
            stroke: #4285f4 !important;
        }

        .user-line {
            stroke: #34a853 !important;
        }

        .draw-area {
            fill: rgba(200, 230, 255, 0.1);
        }
    </style>
</head>
<body>
<h1>纹样修复师</h1>

<div class="container">
    <div class="left-panel">
        <button id="axisTypeBtn">对称轴类型</button>
        <button id="pattern1Btn" class="pattern-btn">图案1</button>
        <button id="pattern2Btn" class="pattern-btn">图案2</button>
        <button id="clearBtn" class="clear-btn">清空</button>
        <button id="completeBtn" class="complete-btn">完成</button>
    </div>

    <div class="canvas-container">
        <canvas id="canvas" width="640" height="640"></canvas>
    </div>

    <div class="right-panel">
        <button id="drawPointBtn">描点</button>
        <button id="cancelBtn">取消</button>
        <button id="drawLineBtn">连线</button>
        <button id="undoBtn">撤销</button>
    </div>
</div>

<script>
    // 初始化画布
    const canvas = document.getElementById('canvas');
    const ctx = canvas.getContext('2d');

    // 状态管理
    const state = {
        gridSize: 40, // 网格尺寸改为30
        axisType: 'vertical',
        generatedLines: [],  // 生成的原始图案
        mirrorLines: [],     // 镜像图案
        userPoints: [],     // 用户描点
        userLines: [],       // 用户连线
        tempLine: null,     // 临时线段
        actionHistory: [],  // 操作历史
        isChecking: false,  // 检查状态
        errorPoints: [],     // 错误点
        errorLines: [], // 新增错误线段存储
        mode: 'none',         // 当前模式
        curButton: 1
    };

    // DOM元素
    const axisTypeBtn = document.getElementById('axisTypeBtn');
    const pattern1Btn = document.getElementById('pattern1Btn');
    const pattern2Btn = document.getElementById('pattern2Btn');
    const clearBtn = document.getElementById('clearBtn');
    const completeBtn = document.getElementById('completeBtn');
    const drawPointBtn = document.getElementById('drawPointBtn');
    const cancelBtn = document.getElementById('cancelBtn');
    const drawLineBtn = document.getElementById('drawLineBtn');
    const undoBtn = document.getElementById('undoBtn');

    // 事件监听
    axisTypeBtn.addEventListener('click', changeAxisType);
    pattern1Btn.addEventListener('click', () => generatePattern(1));
    pattern2Btn.addEventListener('click', () => generatePattern(2));
    clearBtn.addEventListener('click', clearCanvasNotClearGeneratedLines);
    completeBtn.addEventListener('click', checkSymmetry);
    drawPointBtn.addEventListener('click', () => setMode('drawPoint'));
    cancelBtn.addEventListener('click', cancelLastPoint);
    drawLineBtn.addEventListener('click', () => setMode('drawLine'));
    undoBtn.addEventListener('click', undoLastAction);
    canvas.addEventListener('click', handleCanvasClick);
    canvas.addEventListener('mousemove', handleCanvasMouseMove);

    // 初始化画布
    initCanvas();

    /* 核心功能函数 */
    function initCanvas() {
        drawGrid();
        drawAxis();
    }

    // 绘制网格（30px网格）
    function drawGrid() {
        ctx.strokeStyle = 'black';
        ctx.lineWidth = 1;
        ctx.setLineDash([5, 2]);

        let center = canvas.width/2;
        for (let x = 0; x <= canvas.width; x += state.gridSize) {
            if (x === center && state.axisType === 'vertical'){
                continue;
            }
            ctx.beginPath();
            ctx.moveTo(x, 0);
            ctx.lineTo(x, canvas.height);
            ctx.stroke();
        }

        for (let y = 0; y <= canvas.height; y += state.gridSize) {

            if (y === center && state.axisType === 'horizontal'){
                continue;
            }
            ctx.beginPath();
            ctx.moveTo(0, y);
            ctx.lineTo(canvas.width, y);
            ctx.stroke();
        }

        ctx.setLineDash([]);
    }

    // 绘制对称轴
    function drawAxis() {
        ctx.strokeStyle = 'red';
        ctx.lineWidth = 2;
        ctx.setLineDash([5, 5]);

        const centerX = canvas.width / 2;
        const centerY = canvas.height / 2;

        ctx.beginPath();
        switch (state.axisType) {
            case 'vertical':
                ctx.moveTo(centerX, 0);
                ctx.lineTo(centerX, canvas.height);
                break;
            case 'horizontal':
                ctx.moveTo(0, centerY);
                ctx.lineTo(canvas.width, centerY);
                break;
            case 'diagonal':
                ctx.moveTo(0, 0);
                ctx.lineTo(canvas.width, canvas.height);
        }
        ctx.stroke();
        ctx.setLineDash([]);
    }

    // 绘制所有元素
    function drawAll() {
        ctx.clearRect(0, 0, canvas.width, canvas.height);
        drawGrid();
        drawAxis();
        drawDrawingArea();

        // 绘制生成的原始图案（蓝色）
        ctx.strokeStyle = '#4285f4';
        ctx.lineWidth = 3;
        state.generatedLines.forEach(line => {
            ctx.beginPath();
            ctx.moveTo(line.start.x, line.start.y);
            ctx.lineTo(line.end.x, line.end.y);
            ctx.stroke();
        });

        // 绘制用户内容（绿色）
        ctx.strokeStyle = '#34a853';
        ctx.lineWidth = 3;
        state.userLines.forEach(line => {
            ctx.beginPath();
            ctx.moveTo(line.start.x, line.start.y);
            ctx.lineTo(line.end.x, line.end.y);
            ctx.stroke();
        });

        // 绘制点
        ctx.fillStyle = 'blue';
        state.userPoints.forEach(point => {
            ctx.beginPath();
            ctx.arc(point.x, point.y, 8, 0, Math.PI * 2);
            ctx.fill();
        });

        // // 绘制错误点
        // ctx.fillStyle = 'red';
        // state.errorPoints.forEach(point => {
        //     ctx.beginPath();
        //     ctx.arc(point.x, point.y, 8, 0, Math.PI * 2);
        //     ctx.stroke();
        // });
        //
        // // 在绘制错误点后添加
        // ctx.strokeStyle = 'red';
        // ctx.lineWidth = 2;
        // state.errorPoints.forEach(point => {
        //     ctx.beginPath();
        //     ctx.arc(point.x, point.y, 12, 0, Math.PI * 2);
        //     ctx.stroke();
        // });
        // 先绘制所有虚线段
        ctx.strokeStyle = 'red';
        ctx.setLineDash([5, 3]);
        state.errorLines.forEach(drawLine);

        // 再统一绘制所有实线警示圈
        ctx.setLineDash([]);
        state.errorLines.forEach(line => {
            ctx.beginPath();
            ctx.arc(line.start.x, line.start.y, 8, 0, Math.PI * 2);
            ctx.stroke();

            ctx.beginPath();
            ctx.arc(line.end.x, line.end.y, 8, 0, Math.PI * 2);
            ctx.stroke();
        });
    }

    // 公共线段绘制方法
    function drawLine(line) {
        ctx.beginPath();
        ctx.moveTo(line.start.x, line.start.y);
        ctx.lineTo(line.end.x, line.end.y);
        ctx.stroke();
    }

    // 绘制可操作区域提示
    function drawDrawingArea() {
        ctx.fillStyle = 'rgba(200, 230, 255, 0.1)';
        const centerX = canvas.width / 2;
        const centerY = canvas.height / 2;

        switch (state.axisType) {
            case 'vertical':
                ctx.fillRect(centerX, 0, canvas.width, canvas.height);
                break;
            case 'horizontal':
                ctx.fillRect(0, centerY, canvas.width, canvas.height);
                break;
            case 'diagonal':
                ctx.beginPath();
                ctx.moveTo(centerX, centerY);
                ctx.lineTo(canvas.width, centerY);
                ctx.lineTo(canvas.width, canvas.height);
                ctx.closePath();
                ctx.fill();
        }
    }

    // 切换对称轴类型
    function changeAxisType() {
        const types = ['vertical', 'horizontal', 'diagonal'];
        const currentIndex = types.indexOf(state.axisType);
        state.axisType = types[(currentIndex + 1) % types.length];

        // 更新按钮文本
        const texts = ['垂直对称轴', '水平对称轴', '斜向对称轴'];
        axisTypeBtn.textContent = texts[(currentIndex + 1) % texts.length];

        clearCanvas();
    }

    let clickNum1 = 0;
    let clickNum2 = 0;

    // 生成图案（严格在左侧）
    function generatePattern(type) {
        clearCanvas();

        let points;
        if (type === 1) {
            points = patterns[state.axisType][0][clickNum1 % patterns[state.axisType][0].length];
            clickNum1++;
            state.curButton = 1;
        } else {
            points = patterns[state.axisType][1][clickNum2 % patterns[state.axisType][1].length];
            clickNum2++;
            state.curButton = 2;
        }

        state.generatedLines = [];
        for (let i = 0; i < points.length - 1; i++) {
            state.generatedLines.push({
                start: points[i],
                end: points[i + 1]
            });
        }

        // 生成镜像
        state.mirrorLines = createMirror(state.generatedLines);
        drawAll();
        saveStateToHistory();
    }


    const X = canvas.width / 2;
    const Y = canvas.height / 2;
    const L = state.gridSize;
    //图案数据集
    const patterns = {
        'vertical': [
            [
                [ // 回纹
                    {x: X, y: Y + L * 2},
                    {x: X - L * 3, y: Y + L * 2},
                    {x: X - L * 3, y: Y},
                    {x: X - L, y: Y},
                    {x: X - L, y: Y - L * 2},
                    {x: X - L * 7, y: Y - L * 2},
                    {x: X - L * 7, y: Y},
                    {x: X - L * 5, y: Y},
                    {x: X - L * 5, y: Y + L * 2},
                    {x: X - L * 7, y: Y + L * 2}
                ],
                [ // 方胜纹
                    {x: X, y: Y - L * 2},
                    {x: X - L * 3, y: Y - L * 4},
                    {x: X - L * 8, y: Y},
                    {x: X - L * 3, y: Y + L * 4},
                    {x: X, y: Y + L * 2},
                    {x: X - L * 3, y: Y},
                    {x: X, y: Y - L * 2}
                ],
                [ // 万不断
                    {x: X, y: Y - L * 5},
                    {x: X - L * 7, y: Y - L * 5},
                    {x: X - L * 7, y: Y - L},
                    {x: X - L * 5, y: Y - L},
                    {x: X - L * 5, y: Y - L * 3},
                    {x: X - L * 3, y: Y - L * 3},
                    {x: X - L * 3, y: Y - L},
                    {x: X - L * 5, y: Y - L},
                    {x: X - L * 5, y: Y + L},
                    {x: X - L * 5, y: Y + L * 3},
                    {x: X - L * 3, y: Y + L * 3},
                    {x: X - L * 3, y: Y + L},
                    {x: X - L * 5, y: Y + L},
                    {x: X - L * 7, y: Y + L},
                    {x: X - L * 7, y: Y + L * 5},
                    {x: X, y: Y + L * 5}
                ]
            ],
            [
                [ // 大象
                    {x: X - L * 5, y: Y - L * 2},
                    {x: X - L * 4, y: Y - L},
                    {x: X - L * 4, y: Y},
                    {x: X - L * 5, y: Y + L},
                    {x: X - L * 6, y: Y},
                    {x: X - L * 7, y: Y + L},
                    {x: X - L * 7, y: Y},
                    {x: X - L * 5, y: Y - L * 2},
                    {x: X - L * 2, y: Y - L * 2},
                    {x: X - L, y: Y - L},
                    {x: X - L, y: Y + L * 2},
                    {x: X - L * 2, y: Y + L * 2},
                    {x: X - L * 2, y: Y + L},
                    {x: X - L * 4, y: Y + L},
                    {x: X - L * 4, y: Y + L * 2},
                    {x: X - L * 5, y: Y + L * 2},
                    {x: X - L * 5, y: Y + L}
                ],
                [ // 三角形
                    {x: X - L, y: Y - L * 2},
                    {x: X - L * 4, y: Y - L * 3},
                    {x: X - L * 2, y: Y + L * 3},
                    {x: X - L, y: Y - L * 2}
                ],
                [ // 2
                    {x: X - L * 3, y: Y - L * 2},
                    {x: X - L, y: Y - L * 2},
                    {x: X - L, y: Y},
                    {x: X - L * 3, y: Y},
                    {x: X - L * 3, y: Y + L * 2},
                    {x: X - L, y: Y + L * 2}
                ]
            ]

        ],
        'horizontal':
            [
                [
                    [ //四角星
                        {x: X - L * 3, y: Y},
                        {x: X - L, y: Y - L},
                        {x: X, y: Y - L * 3},
                        {x: X + L, y: Y - L},
                        {x: X + L * 3, y: Y}
                    ],
                    [ //箭头
                        {x: X - L * 3, y: Y},
                        {x: X - L, y: Y - L * 2},
                        {x: X - L, y: Y - L},
                        {x: X + L * 3, y: Y - L},
                        {x: X + L * 3, y: Y}
                    ],
                    [ //飞机
                        {x: X - L * 5, y: Y},
                        {x: X - L * 4, y: Y - L},
                        {x: X - L, y: Y - L},
                        {x: X - L * 2, y: Y - L * 2},
                        {x: X, y: Y - L * 3},
                        {x: X, y: Y - L},
                        {x: X + L * 2, y: Y - L},
                        {x: X + L * 5, y: Y - L * 3},
                        {x: X + L * 5, y: Y}
                    ],
                    [ //小鱼
                        {x: X - L * 2, y: Y},
                        {x: X, y: Y - L * 3},
                        {x: X, y: Y},
                        {x: X + L, y: Y - L},
                        {x: X + L, y: Y},
                    ],
                ],
                [
                    [ //梯形
                        {x: X - L * 2, y: Y - L},
                        {x: X - L * 2, y: Y - L * 3},
                        {x: X, y: Y - L * 3},
                        {x: X + L * 2, y: Y - L},
                        {x: X - L * 2, y: Y - L}
                    ],
                    [ //旗子
                        {x: X, y: Y - L * 2},
                        {x: X, y: Y - L * 6},
                        {x: X + L * 2, y: Y - L * 4},
                        {x: X, y: Y - L * 4}
                    ]
                ]
            ],
        'diagonal':
            [[
                [ //书1
                    {x: X - L * 4, y: Y - L * 4},
                    {x: X - L * 3, y: Y + L},
                    {x: X, y: Y + L * 4},
                    {x: X + L * 4, y: Y + L * 4}
                ],
                [ //书2
                    {x: X - L * 2, y: Y - L * 2},
                    {x: X - L * 4, y: Y - L * 2},
                    {x: X - L * 4, y: Y + L * 2},
                    {x: X - L * 2, y: Y + L * 2},
                    {x: X, y: Y + L * 4},
                    {x: X + L * 4, y: Y + L * 4}
                ],
                [ //箭头
                    {x: X - L * 2, y: Y - L * 2},
                    {x: X - L * 2, y: Y + L * 2},
                    {x: X - L, y: Y + L},
                    {x: X + L * 2, y: Y + L * 4},
                    {x: X + L * 2, y: Y + L * 2}
                ]
            ],
                [
                    [ //折线
                        {x: X - L * 2, y: Y - L * 4},
                        {x: X, y: Y - L * 2},
                        {x: X + L * 2, y: Y - L * 4},
                        {x: X + L * 4, y: Y - L * 2},
                        {x: X + L * 2, y: Y},
                        {x: X + L * 4, y: Y + L * 2}
                    ],
                    [ //平行四边形
                        {x: X, y: Y - L * 2},
                        {x: X + L * 5, y: Y - L * 2},
                        {x: X + L * 7, y: Y},
                        {x: X + L * 2, y: Y},
                        {x: X, y: Y - L * 2}
                    ]

                ]]
    }


    // 创建镜像线条
    function createMirror(lines) {
        return lines.map(line => ({
            start: mirrorPoint(line.start),
            end: mirrorPoint(line.end)
        }));
    }

    // 坐标镜像计算
    function mirrorPoint(point) {
        const centerX = canvas.width / 2;
        const centerY = canvas.height / 2;

        switch (state.axisType) {
            case 'vertical':
                return {x: 2 * centerX - point.x, y: point.y};
            case 'horizontal':
                return {x: point.x, y: 2 * centerY - point.y};
            case 'diagonal':
                return {x: point.y, y: point.x};
        }
    }

    // 检查绘制区域
    function isInDrawingArea(point) {
        const centerX = canvas.width / 2;
        const centerY = canvas.height / 2;

        switch (state.axisType) {
            case 'vertical':
                return point.x >= centerX;
            case 'horizontal':
                return point.y >= centerY;
            case 'diagonal':
                return state.curButton == 1 ? point.x >= point.y : point.x <= point.y;
        }
    }

    // 处理画布点击
    function handleCanvasClick(e) {
        const rect = canvas.getBoundingClientRect();
        const pos = {
            x: e.clientX - rect.left,
            y: e.clientY - rect.top
        };

        const point = snapToGrid(pos);
        if (!isInDrawingArea(point)) return;

        // 辅助函数：判断点是否相同
        const pointsAreEqual = (p1, p2) => p1.x === p2.x && p1.y === p2.y;

        if (state.mode === 'drawPoint') {
            // 检查是否已存在相同坐标的点
            const exists = state.userPoints.some(p => pointsAreEqual(p, point));
            if (!exists) {
                state.userPoints.push(point);
                saveStateToHistory();
                drawAll();
            }
        }
        else if (state.mode === 'drawLine') {
            const clickedPoint = findPointAt(point.x, point.y);
            if (!clickedPoint) return;

            if (!state.tempLine) {
                // 首次点击设置起点
                state.tempLine = { start: clickedPoint, end: null };
            } else {
                // 检查是否点击相同点
                if (pointsAreEqual(state.tempLine.start, clickedPoint)) {
                    // 允许继续连线操作，保留当前起点
                    return;
                }

                // 添加有效线段
                state.userLines.push({
                    start: state.tempLine.start,
                    end: clickedPoint
                });

                // 重置临时线段并保存状态
                state.tempLine = null;
                saveStateToHistory();
            }
            drawAll();
        }
    }

    // 处理鼠标移动
    function handleCanvasMouseMove(e) {
        if (state.mode === 'drawLine' && state.tempLine) {
            const rect = canvas.getBoundingClientRect();
            const pos = {
                x: e.clientX - rect.left,
                y: e.clientY - rect.top
            };
            const point = snapToGrid(pos);
            state.tempLine.end = isInDrawingArea(point) ? point : state.tempLine.start;
            drawAll();
        }
    }

    // 吸附到网格
    function snapToGrid(pos) {
        return {
            x: Math.round(pos.x / state.gridSize) * state.gridSize,
            y: Math.round(pos.y / state.gridSize) * state.gridSize
        };
    }

    // 检查对称性
    function checkSymmetry() {
        if (!state.mirrorLines.length) {
            alert('请先生成一个图案！');
            return;
        }

        state.errorPoints = [];
        state.errorLines = []; // 清空错误线段

        // 检查点对称性
        const mirrorPoints = new Set();
        state.mirrorLines.forEach(line => {
            mirrorPoints.add(`${line.start.x},${line.start.y}`);
            mirrorPoints.add(`${line.end.x},${line.end.y}`);
        });

        // 检查线段匹配性
        const matchedMirrorLines = new Set();
        state.mirrorLines.forEach(mLine => {
            const found = state.userLines.find(uLine =>
                (matchLine(uLine, mLine)) ||
                (matchLine(uLine, {start: mLine.end, end: mLine.start}))
            );

            if (found) {
                matchedMirrorLines.add(lineKey(mLine));
            } else {
                state.errorPoints.push(mLine.start, mLine.end);
            }
        });

        // 检查多余线段
        state.userLines.forEach(uLine => {
            const mirroredLine = {
                start: mirrorPoint(uLine.start),
                end: mirrorPoint(uLine.end)
            };

            const isCorrect = state.generatedLines.some(mLine =>
                matchLine(mLine, mirroredLine) ||
                matchLine(mLine, {start: mirroredLine.end, end: mirroredLine.start})
            );

            if (!isCorrect) {
                state.errorLines.push(uLine); // 记录错误线段
            }
        });

        if (state.errorPoints.length === 0 && state.errorLines.length === 0) {
            showStarEffect();
        }
        drawAll();
    }

    // 辅助函数：线段匹配判断
    function matchLine(lineA, lineB) {
        return distance(lineA.start, lineB.start) === 0 &&
            distance(lineA.end, lineB.end) === 0;
    }

    // 辅助函数：生成线段唯一标识
    function lineKey(line) {
        return `${line.start.x},${line.start.y}-${line.end.x},${line.end.y}`;
    }

    // 其他辅助函数
    function distance(p1, p2) {
        return Math.hypot(p1.x - p2.x, p1.y - p2.y);
    }

    function findPointAt(x, y) {
        const tolerance = 5;
        for (const point of state.userPoints) {
            if (distance(point, {x, y}) <= tolerance) return point;
        }
        return null;
    }

    function showStarEffect() {
        const colors = ['#ff6b6b', '#ffe66d', '#4ecdc4', '#ff9f1c'];
        for (let i = 0; i < 500; i++) {
            const star = document.createElement('div');
            star.className = 'star';
            star.style.width = '15px';
            star.style.height = '15px';
            star.style.animation = "fall-down 3s linear";
            star.style.left = Math.random() * window.innerWidth + 'px';
            star.style.top = Math.random() * window.innerHeight + 'px';
            star.style.backgroundColor = colors[Math.floor(Math.random() * colors.length)];
            document.body.appendChild(star);
            star.addEventListener('animationend', () => star.remove());
        }
    }

    function clearCanvasNotClearGeneratedLines(){
        state.userPoints = [];
        state.userLines = [];
        state.tempLine = null;
        state.errorPoints = [];
        state.errorLines = [];
        drawAll();
    }

    // 状态管理函数
    function clearCanvas() {
        state.generatedLines = [];
        state.mirrorLines = [];
        clearCanvasNotClearGeneratedLines();
    }

    function setMode(mode) {
        state.mode = mode;
        drawPointBtn.style.backgroundColor = mode === 'drawPoint' ? '#2a9d8f' : '#4ecdc4';
        drawLineBtn.style.backgroundColor = mode === 'drawLine' ? '#2a9d8f' : '#4ecdc4';
    }

    function cancelLastPoint() {
        if (state.userPoints.length > 0) {
            state.userPoints.pop();
            saveStateToHistory();
            drawAll();
        }
    }

    function undoLastAction() {
        if (state.actionHistory.length > 0) {
            const lastState = state.actionHistory.pop();
            state.userPoints = lastState.userPoints;
            state.userLines = lastState.userLines;
            state.tempLine = lastState.tempLine;
            state.errorPoints = [];
            state.errorLines = [];
            drawAll();
        }
    }

    function saveStateToHistory() {
        state.actionHistory.push({
            userPoints: [...state.userPoints],
            userLines: [...state.userLines],
            tempLine: state.tempLine ? {...state.tempLine} : null
        });
        if (state.actionHistory.length > 50) state.actionHistory.shift();
    }
</script>
</body>
</html>